--╔════════════════════════════╗══════════════════════════════════════════════════════════════════════════════════════════════════╗
--║       OBJECT HOOKS &       ║ So thinkers never duplicate with multiple rail mods are added, I'll put hooks & thinkers here
--║         THINKERS           ║ It's a pain for development, but it'll make Grind Rails future-compatible.
--╚════════════════════════════╝══════════════════════════════════════════════════════════════════════════════════════════════════╝
if GS_RAILS and GS_RAILS.blockload==true
	GS_RAILS.blockload = false return --Okay, we've skipped all loading phases, remove blockload!
end
if GS_RAILS_SINGLEHOOKS==nil rawset(_G,"GS_RAILS_SINGLEHOOKS",{}) end 
local RAIL = GS_RAILS
local HOOK = GS_RAILS_SINGLEHOOKS --This table shows which hooks we've already added and which ones we haven't.

--LUA_RAILMAIN
if not HOOK.Rail_Main
	HOOK.Rail_Main = true

	--Add fuse so we don't get multiple rail directors somehow.
	addHook("MobjSpawn", RAIL.Director_MobjSpawn, MT_GSRAILDIRECTOR)	

	--Try to make sure the Director won't be "killed" or anything 
	addHook("ShouldDamage", function(s) if s return false end end, MT_GSRAILDIRECTOR)
	addHook("MobjDamage", function(s) if s return true end end, MT_GSRAILDIRECTOR)
	addHook("MobjDeath", function(s) if s return true end end, MT_GSRAILDIRECTOR)

	/*addHook("MobjRemoved", function(s) if not s return end -- 
		if s.GS_SetupRailDirector RAIL.error("Warning! The Rail Director got removed!") end return --
		if ((s.fuse or 0) < 16) and consoleplayer and consoleplayer.name=="Golden Shine" print("\x85"+"Removed overflow 2nd director:\x88"+s) return end --
	end, MT_GSRAILDIRECTOR) */

	
	--MobjSpawn happens before the MapThingSpawn!
	addHook("MobjSpawn", RAIL.RailMobjSpawn, MT_GSRAIL)
	addHook("MapThingSpawn",RAIL.MapThingSpawn, MT_GSRAIL)
	addHook("MobjDeath", RAIL.RailBusted, MT_GSRAIL) 
	addHook("MobjDamage", RAIL.RailBusted, MT_GSRAIL)


	addHook("MapChange", RAIL.MapChange) --Reset RAIL Director and other values!
	addHook("MapLoad", RAIL.MapLoad) --On Map Load, spawn the rail director and setup some values.
	addHook("GameQuit", RAIL.QuitGame) --On gamequit, make sure to remove some flags and such early!

	
	--This object is a tracker for alot of different attached rail objects, often also replacing their colission detection.
	addHook("MobjThinker", RAIL.AttachedThingThinker, MT_GSRAILATTACHEDTHING)
	
	addHook("ShouldDamage", RAIL.PlayerShouldDamage, MT_PLAYER) --Players are immune to crush damage when grinding!
	addHook("MobjDamage", RAIL.PlayerDamage, MT_PLAYER) --Actions when players get damaged on a rail
	addHook("MobjDeath", RAIL.PlayerDeath, MT_PLAYER) --Actions when players die on a rail
	
	--Let jetty's call linedef executors when killed with their "Can Move" flag set to no! Feel free to add this function to any mobj!
	addHook("MobjDeath", RAIL.JettDeath, MT_JETTBOMBER)
	addHook("MobjDeath", RAIL.JettDeath, MT_JETTGUNNER)
end

--LUA_RAILDECOR
if not HOOK.Accessories_Main
	HOOK.Accessories_Main = true
	
	--Rail Dye is an object meant for binary mappers to dye their rails. It doesn't serve much purpose for UDMF.
	addHook("MapThingSpawn", function(s, mapthing)
		if RAIL.IsMTValid(s, mapthing) RAIL.DyeMapThingSpawn(s,mapthing) end
	end, MT_GSRAILDYE)
	
	--Usually the Dye object disappears a few tics after it's spawned and dyed the rails.
	addHook("MobjThinker", RAIL.DyeThinker, MT_GSRAILDYE)
	
	--Rail lights are objects you can either use as decor, or attach to rails to indicate hazards or rail jumps!
	addHook("MapThingSpawn", function(s, mapthing) 
		if RAIL.IsMTValid(s, mapthing) RAIL.LightMapThingSpawn(s, mapthing) end
	end, MT_GSRAILLIGHT)
	
	addHook("MobjThinker", RAIL.LightThinker, MT_GSRAILLIGHT) --Lights need to animate and pulse, thus a MobjThinker was born.
	
	--The pole's an optional accessory that attaches to rails, making them look more structurally sound.
	addHook("MapThingSpawn", function(s, mapthing) 
		if RAIL.IsMTValid(s, mapthing) RAIL.PoleMapThingSpawn(s, mapthing) end
	end, MT_GSRAILPOLE)
end

--LUA_COLLIDE
if not HOOK.Collide_Main
	HOOK.Collide_Main = true
	addHook("MobjCollide", RAIL.GrindRailCollide, MT_GSRAIL) 
	addHook("MobjCollide", RAIL.GrindSegmentCollide, MT_GSRAILSEG)
	addHook("MobjCollide", RAIL.RailObjectCollide, MT_GSRAILATTACHEDTHING)
	addHook("MobjMoveCollide", RAIL.RailObjectCollide, MT_GSRAILATTACHEDTHING)
end

--LUA_RAILGFX
if not HOOK.GFX_MobjThinker
	HOOK.GFX_MobjThinker = true
	addHook("MobjThinker", RAIL.autoframe, MT_GSRAILGFX)
end

--LUA_PREPOST, which then calls on LUA_PLAYER and LUA_GRINDMOBJ, which then call on LUA_MOBJFUNC and LUA_CAMERA, etc.
if not HOOK.ThinkFrames_Main
	HOOK.ThinkFrames_Main = true
	addHook("PreThinkFrame", RAIL.PreThinkFrame)
	addHook("ThinkFrame", RAIL.ThinkFrame)
	addHook("PostThinkFrame", RAIL.PostThinkFrame)
	
	hud.add(RAIL.HUDdraw) --LUA_MENU-HUD
end

--Lastly, sync some stuff.
if not HOOK.NetVars_Sync
	HOOK.NetVars_Sync = true
	addHook("NetVars", function(network)
		GS_RAILS_V = network($)
		
	--	GS_RAILS = network($)
		GS_RAILS.blockload = network($)
		GS_RAILS.MapReady = network($)
		GS_RAILS.maxhook = network($)
		GS_RAILS.INTTIMER = network($)
		
	--	GS_RAILS_SKINS = network($)
		CR_GRINDRAIL = network($)
		GS_RAILS_SETTINGS = network($)
		GS_RAILS_DIRECTOR = network($)
		GS_LOOP_TYPES = network($)
		GS_RAILS_TYPES	= network($)
		
		GS_RAILS_SINGLEHOOKS = network($) --Always do this one last.
	end)
end
